package cn.jesin.css.handler;

import cn.jesin.css.common.DefaultPassword;
import cn.jesin.css.common.Flag;
import cn.jesin.css.common.LoginType;
import cn.jesin.css.entity.OtherAuth;
import cn.jesin.css.mapper.OtherAuthMapper;
import cn.jesin.css.service.RegisterService;
import cn.jesin.css.utils.JwtTokenUtil;
import cn.jesin.css.vo.OtherAuthInfo;
import cn.jesin.css.vo.responseformat.Code;
import cn.jesin.css.vo.responseformat.Result;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author 谷汉斌
 * @description 登录成功处理器（登录＋注册）
 * @createTime 2024/7/31 下午3:47
 */
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private OtherAuthMapper otherAuthMapper;

    @Resource
    private RegisterService registerService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        //如果是手机验证码登录，判断是否是第一次登录，如果是，则注册
        String[] split = userDetails.getUsername().split(":");
        if (split[2].equals(LoginType.VERIFICATION_CODE_LOGIN.getType())) {
            //从数据库取数据
            OtherAuth otherAuth = otherAuthMapper.selectOtherAuthByoAuthTypeAndoAuthId(split[1], split[0]);
            if (otherAuth == null) {
                OtherAuthInfo otherAuthInfo = OtherAuthInfo.builder()
                        .loginType(LoginType.VERIFICATION_CODE_LOGIN.getType())
                        .othType(split[1])
                        .phone(split[0])
                        .password(DefaultPassword.PASSWORD)
                        .build();
                boolean flag = registerService.phonePasswordRegister(otherAuthInfo);
                if (!flag) {
                    renderToken(httpServletResponse, null, false);
                }
            }
        }
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtil.generateToken(userDetails);
        //将token放入请求头中
        renderToken(httpServletResponse, token, true);
    }

    /**
     * 渲染返回 token 页面,因为前端页面接收的都是Result对象，故使用application/json返回
     *
     * @param response 响应
     * @throws IOException 异常
     */
    public void renderToken(HttpServletResponse response, String token, boolean flag) throws IOException {
        ServletOutputStream out = response.getOutputStream();
        Result<Object> result = Result.builder()
                .flag(flag ? Flag.SUCCESS.isCode() : Flag.FAIL.isCode())
                .code(flag ? Code.LOGIN_SUCCESS.getCode() : Code.LOGIN_FAIL.getCode())
                .data(token)
                .message(flag ? Code.LOGIN_SUCCESS.getInfo() : Code.LOGIN_FAIL.getInfo()).build();
        String s = JSON.toJSONString(result);
        out.write(s.getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();
    }
}